use anyhow::Context;
use sea_orm::{ConnectOptions, Database, DatabaseConnection};
use tokio::time::Duration;

pub mod config;

#[derive(Clone)]
pub struct AppState {
    pub db_pool: DatabaseConnection,
}

pub async fn db_init() -> anyhow::Result<DatabaseConnection, anyhow::Error> {
    // Retrieve the database URL from the environment variables
    let database_url = dotenv::var("database.url").expect("Failed to get database.url");

    // Attempt to connect to the database
    let db = Database::connect(&database_url)
        .await
        .context("Failed to connect to the database")?;
    Ok(db)
}

pub async fn gen_db_pool(database_url: String) -> Result<DatabaseConnection, anyhow::Error> {
    let mut opt = ConnectOptions::new(database_url);
    opt.max_connections(100)
        .min_connections(5)
        .connect_timeout(Duration::from_secs(8))
        .acquire_timeout(Duration::from_secs(8))
        .idle_timeout(Duration::from_secs(8))
        .max_lifetime(Duration::from_secs(8))
        .sqlx_logging(true)
        .sqlx_logging_level(log::LevelFilter::Debug)
        .set_schema_search_path("album"); // Setting default PostgreSQL schema

    let db_result = Database::connect(opt).await;

    match db_result {
        Ok(db) => Ok(db),
        Err(err) => {
            tracing::error!("{:?}", err);
            return Err(anyhow::Error::msg(err));
        }
    }
}
